package cn.turboinfo.dongying.api.provider.admin.impl.log;

import cn.turboinfo.dongying.api.domain.admin.service.log.OperationLogService;
import cn.turboinfo.dongying.api.entity.admin.exception.log.OperationLogException;
import cn.turboinfo.dongying.api.entity.admin.pojo.log.OperationLog;
import cn.turboinfo.dongying.api.entity.admin.pojo.log.OperationLogCreator;
import cn.turboinfo.dongying.api.entity.admin.pojo.log.OperationLogUpdater;
import cn.turboinfo.dongying.api.provider.admin.repository.database.log.OperationLogDAO;
import cn.turboinfo.dongying.api.provider.admin.repository.database.log.OperationLogPO;
import lombok.RequiredArgsConstructor;
import net.sunshow.toolkit.core.qbean.api.request.QPage;
import net.sunshow.toolkit.core.qbean.api.request.QRequest;
import net.sunshow.toolkit.core.qbean.api.response.QResponse;
import net.sunshow.toolkit.core.qbean.helper.component.request.QBeanCreatorHelper;
import net.sunshow.toolkit.core.qbean.helper.component.request.QBeanUpdaterHelper;
import net.sunshow.toolkit.core.qbean.helper.service.impl.AbstractQServiceImpl;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;

@RequiredArgsConstructor
@Service
public class OperationLogServiceImpl extends AbstractQServiceImpl<OperationLog> implements OperationLogService {
    private final OperationLogDAO operationLogDAO;

    @Override
    public Optional<OperationLog> getById(Long id) {
        return operationLogDAO.findById(id).map(this::convertQBean);
    }

    @Override
    public OperationLog getByIdEnsure(Long id) {
        return getById(id).orElseThrow(this.getExceptionSupplier("未找到数据, id=" + id, null));
    }

    @Override
    public List<OperationLog> findByIdCollection(Collection<Long> idCollection) {
        return convertStreamQBeanToList(operationLogDAO.findByIdInOrderByIdDesc(idCollection).stream());
    }

    @Override
    @Transactional
    public OperationLog save(OperationLogCreator creator) throws OperationLogException {
        OperationLogPO operationLogPO = new OperationLogPO();

        QBeanCreatorHelper.copyCreatorField(operationLogPO, creator);

        return convertQBean(operationLogDAO.save(operationLogPO));
    }

    @Override
    @Transactional
    public OperationLog update(OperationLogUpdater updater) throws OperationLogException {
        OperationLogPO operationLogPO = getEntityWithNullCheckForUpdate(updater.getUpdateId(), operationLogDAO);

        QBeanUpdaterHelper.copyUpdaterField(operationLogPO, updater);

        return convertQBean(operationLogPO);
    }

    @Override
    public QResponse<OperationLog> findAll(QRequest request, QPage requestPage) {
        return convertQResponse(findAllInternal(request, requestPage));
    }

    private Page<OperationLogPO> findAllInternal(QRequest request, QPage requestPage) {
        return operationLogDAO.findAll(convertSpecification(request), convertPageable(requestPage));
    }

    @Override
    @Transactional
    public void deleteById(Long id) throws OperationLogException {
        OperationLogPO operationLogPO = getEntityWithNullCheckForUpdate(id, operationLogDAO);
        operationLogPO.setDeletedTime(System.currentTimeMillis());
    }

    @Override
    protected Supplier<? extends RuntimeException> getExceptionSupplier(String message,
                                                                        Throwable cause) {
        return () -> new OperationLogException(message, cause);
    }
}
